<html>
<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<title>Expr Family Objects by Shahrokh Yadegari</title>
<style>

HTML {
	background:  #ffffff;
	color: 	     #000000;
	font-size:   12.7pt; /* this is because there were many <p> missing. We can change this value to 7pt to easily detect missing <p> */
	line-height: 1.6;
}
BODY {
	width: 	    6.5in;
	margin-left: 0.8in;
	font-family: Helvetica, Arial, sans-serif;
	/*font-family: Times, Times New Roman, serif;*/
	}
H1 {
	font-size:   32.7pt;
	text-align:  center;
}
H2 {
	font-size:   22.7pt;
	text-align:  left;
}
H3 {
	font-size:   14.7pt;
	text-align:  left;
}
H4 {
	font-size:   12.7pt;
	text-align:  left;
}
H5 {
	font-size:   10.7pt;
	text-align:  left;
}
H6 {
	font-size:   10.7pt;
	text-align:  left;
}
PRE {
   font-size: 80%;
   background-color:rgb(240, 240, 240);
   text-align:  left;
   border-radius: 8px;
   padding: 8px;
}

ol{
	font-size:   14.5pt;
	text-align:  left;
	line-height: 1.6;
	}


p{
	font-size:   12pt;
	text-align:  left;
	line-height: 1.6;
}


/* standard link */

a:link {
    text-decoration: none;
	color: #333399;
}

a:visited {
    text-decoration: none;
	color: #333399;
}

a:hover {
    text-decoration: underline;
	/*color: grey;*/
	color: black;
	background-color:rgb(238, 238, 228);
}

a:active {
    text-decoration: none;
	color: #333399;
}


/* green link (like a button) */

a.green:link {
	font-family:sans-serif;
	background-color: #4CAF50; /* Green */
    border-radius: 4px;
    color: white;
    padding: 0px 8px ;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 80%;

}

a.green:hover {
    text-decoration: none;
	background-color: #4CAF50;
}

a.green:visited {
	color: white;
}

/* standard images */

IMG {

    display: block;
    margin: 0 auto;
    width: auto;


}

mark {
background-color: rgb(255, 240, 179);
}

p.fig {
text-align: center;
}

/* responsive css for small "devices" */

@media screen and (max-device-width: 700px) {
    body {
    padding: 10px;
	width: 	    auto;
	margin-left: 6px;
    }
}

/* responsive css for small "browser window" */

@media screen and (max-width: 701px) {
    body {
    padding: 10px;
	width: 	    auto;
	margin-left: 6px;
    }
}
</style>

</head>
<body>

<h2>
<br>
<font face="Helvetica, Arial, sans-serif">Expr family of objects
by <a href="https://yadegari.org">Shahrokh Yadegari</a></font></h2>

<br> Back to the <a href="https://yadegari.org/software/">Software Page</a>
<br>
<br>

<hr width="100%" size="2" align="left">

<h2 id="Expr..Expr...Fexpr.">[expr], [expr~], [fexpr~]</h2>

<p>Based on original sources from IRCAM&rsquo;s jMax
Released under BSD License.</p>

<p>The <strong>[expr]</strong> family is a set of C-like expression evaluation objects for the graphical music language Pure Data. It used to come as an &lsquo;extra&rsquo; external, but it is now a built-in native object.</p>

<p><strong>[expr]</strong> runs in control rate and evaluates C-like expressions. See below for the list of operators. Multiple expressions separated by semicolons can be defined in a single <strong>[expr]</strong> object and this results in multiple outlets (up to 100, each for each expression). Expressions are evaluated from right to left (which means that the bottom expression will be the first executed.) The number of inlets in expr are defined by variables that take a few different forms: <strong>$i#</strong>, <strong>$i#</strong> and <strong>$s#</strong> for 'integers', 'floats' and 'symbols' ('#' is an inlet number from 1 up to 100, ordered from left to right). As an example, we can have 3 inlets defined as "$i1", "$f2" and "$s3", where:</p>

<ul>
<li><strong>$i1</strong> is the input from the first (left) inlet and is treated as an integer</li>
<li><strong>$f2</strong> is the input from the second (middle) inlet and is treated as a float</li>
<li><strong>$s3</strong> is the input from the third (middle) and expects a symbol</li>
</ul>


<p>Arrays and variables (defined using the [value] object) can be accessed the same way one dimensional arrays are accessed in C; for example, &ldquo;valx + 10&rdquo; will be evaluated to the value of variable &lsquo;valx&rsquo; + 10 and &ldquo;tabname[5]&rdquo; will be evaluated to be the 5th element of an array named &ldquo;tabname&rdquo;. The name of the arrays can also be given by an input; for example &ldquo;$s2[5]&rdquo; will be evaluated to be the 5 element of the array whose symbol has been passed in inlet 2.</p>

<p>Type conversion from a float input to an integer is done automatically if the inlet is defined as an integer. Conversely, you can convert it explicitly by using functions (see below for the list of functions).</p>

<p><strong>[expr]</strong> is also able to manipulate and output symbols. A symbol is written as a string with quotes around it, such as "hello", or as a symbol input <strong>$s#</strong> such as <strong> $s2</strong>. For more information about supported string manipulation functions see below.

<p><strong>[expr~]</strong> is designed to efficiently combine signal and control stream processing by vector operations on the basis of the audio block size. The operations, functions, and syntax for <strong>[expr~]</strong> is just like <strong>[expr]</strong> with the addition of the <strong>$v#</strong> variable for signal vector input (also numbered up to 100). The '$v' is needed at least for the first and main input, so:</p>

<ul>
<li><strong>$v1</strong> - means the first inlet is a signal input</li>
<li><strong>$i2</strong> - means the second inlet is an integer input</li>
<li><strong>$f2</strong> - means the third inlet is a float input</li>
<li><strong>$s4</strong> - means the fourth inlet is a symbol input</li>
</ul>


<p>The result of an expression from <strong>[expr~]</strong> is also an audio signal and multiple expressions up to 100 can also be defined via semicolons.</p>

<p>Note for MSP users: Currently in the MSP version all signal inputs should come first followed by other types of inlet. (There seems to be no way of mixing signal and other types of inlets in their order in Max/MSP, if you know otherwise, please let me know.) This means that signal inlets cannot be mixed with other types of inlets. For example, [expr~ $v1 + $f2 + $v3] is not legal. The second and third inlet should be switched and [expr~ $v1 + $v2 + $f3] should be used instead. In Pd you can mix them in any way you want.</p>

<p>The <strong>[fexpr~]</strong> object provides a flexible mechanism for building FIR and IIR filters by evaluating expressions on a sample by sample basis and providing access to prior samples of the input and output audio streams. When fractional offset is used, <strong>[fexpr~]</strong> uses linear interpolation to determine the value of the indexed sample. The operations, functions, and syntax for <strong>[fexpr~]</strong> is just like <strong>[expr]</strong> with the addition of <strong>$x#</strong> and <strong>$y#</strong> variables. The <strong>[fexpr~]</strong> object can access previous input and output samples up to the block size (64 by default).<p>


<p><strong>$x#</strong> is used to denote a signal input whose samples we would like to access. The syntax is $x followed by '#' (the inlet number up to 100) and the samples indexed by brackets, for example $x1[-1] specifies the previous sample of the first inlet. Therefore, if we are to build a simple filter which replaces every sample by the average of that sample and its previous one, we would use <strong>[fexpr~ ($x1[0] + $x1[-1]) / 2]</strong>. For ease of when the brackets are omitted, the current sample is implied, so we can write the previous filter expression as follows: <strong>[fexpr~ ($x1 + $x1[-1]) / 2]</strong>. To build IIR filters <strong>$y#</strong> is used to access the previous output samples indexed from -1 inside brackets. Note now that '#' here is used to define the outlet number.</p>

<p>The first inlet also needs to be a signal input ($x1), the output of <strong>[fexpr~]</strong> is a signal output and multiple expressions can also be defined via semicolons and each will correspond to an outlet that can be accessed by '$y#'. Note that '$v#' is not allowed in <strong>[fexpr~]</strong>, so:</p>

<ul>
<li><strong>$x1[n]</strong> - means the first inlet is a signal input and 'n' is an index from 0 to -block size</li>
<li><strong>$y1[n]</strong> - is used to access output samples from the first expression and 'n' is an index from -1 to -block size</li>
<li><strong>$i2</strong> - means the second inlet is an integer input</li>
<li><strong>$f2</strong> - means the third inlet is a float input</li>
<li><strong>$s4</strong> - means the fourth inlet is a symbol input</li>
</ul>

<hr width="100%" size="2" align="left">

<h3 id="operators">The operators [expr], [expr~] and [fexpr~] support (listed from highest precedence to lowest) are as follows:</h3>

<table>
<thead>
<tr>
<th>  </th>
<th>  </th>
<th>  </th>
</tr>
</thead>
<tbody>
<tr>
<td>~ </td>
<td> One&rsquo;s complement</td>
<td> </td>
</tr>
<tr>
<td>*</td>
<td> Multiply</td>
<td> </td>
</tr>
<tr>
<td>/ </td>
<td>Divide</td>
<td> </td>
</tr>
<tr>
<td>%</td>
<td> Modulo</td>
<td> </td>
</tr>
<tr>
<td>+ </td>
<td>Add</td>
<td> </td>
</tr>
<tr>
<td>- </td>
<td>Subtract</td>
<td> </td>
</tr>
<tr>
<td>&lt;&lt;</td>
<td> Shift Left</td>
<td> </td>
</tr>
<tr>
<td> >></td>
<td> Shift Right</td>
<td> </td>
</tr>
<tr>
<td>&lt; </td>
<td>Less than (boolean)</td>
<td> </td>
</tr>
<tr>
<td>&lt;=</td>
<td> Less than or equal (boolean)</td>
<td> </td>
</tr>
<tr>
<td>> </td>
<td>Greater than (boolean)</td>
<td> </td>
</tr>
<tr>
<td> >= </td>
<td>Greater than or equal (boolean)</td>
<td> </td>
</tr>
<tr>
<td> == </td>
<td>Equal (boolean)</td>
<td> </td>
</tr>
<tr>
<td>!= </td>
<td>Not equal (boolean)</td>
<td> </td>
</tr>
<tr>
<td>&amp; </td>
<td>Bitwise And</td>
<td> </td>
</tr>
<tr>
<td>^</td>
<td> Exclusive Or</td>
<td> </td>
</tr>
<tr>
<td>| </td>
<td>Bitwise Or</td>
<td> </td>
</tr>
<tr>
<td> &amp;&amp;</td>
<td> Logical And (boolean)</td>
<td> </td>
</tr>
<tr>
<td>|| </td>
<td>Logical Or (boolean)</td>
<td> </td>
</tr>
<tr>
<td>! </td>
<td>Logical Not (boolean)</td>
<td> </td>
</tr>
</tbody>
</table>

<h3 id="functions">The supported functions for [expr], [expr~] and [fexpr~] are:</h3>

<B>General Functions</B>

<table border="1" cellpadding ="10">
<thead>
<tr>
<th> Function <BR>Name </th>
<th> # of <BR>Args </th>
<th style="text-align: left">
  Description </th>
</tr>
</thead>
<tbody>
<tr>
<td> if() </td>
<td>3</td>
<td> conditional  - if (condition, IfTrue-expr, IfFalse-expr) - in [expr~] if &lsquo;condition&rsquo; is a signal, the result will be determined on sample by sample basis (added in version 0.4) </td>
</tr>
<tr>
<td> int() </td>
<td> 1 </td>
<td> convert to integer </td>
</tr>
<tr>
<td> rint()</td>
<td> 1 </td>
<td> round a float to a nearby integer </td>
</tr>
<tr>
<td>floor()</td>
<td>1</td>
<td>largest integral value not greater than argument (added in version 0.4)</td>
</tr>
<tr>
<td>ceil()</td>
<td>1</td>
<td>smallest integral value not less than argument (added in version 0.4)</td>
</tr>
<tr>
<td>float()</td>
<td> 1 </td>
<td>convert to float </td>
</tr>
<tr>
<td>min()</td>
<td>2</td>
<td>minimum</td>
</tr>
<tr>
<td>max()</td>
<td>2</td>
<td>maximum</td>
</tr>
<tr>
<td>abs()</td>
<td>1</td>
<td>absolute value (added in version 0.3)</td>
</tr>
<tr>
<td>if()</td>
<td>3</td>
<td>conditional  - if (condition, IfTrue-expr, IfFalse-expr) - in [expr~] if &lsquo;condition&rsquo; is a signal, the result will be determined on sample by sample basis (added in version 0.4)</td>
</tr>
<tr>
<td>isinf()</td>
<td>1</td>
<td>is the value infinite (added in version 0.4)</td>
</tr>
<tr>
<td>finite()</td>
<td>1</td>
<td>is the value finite (added in version 0.4)</td>
</tr>
<tr>
<td>isnan()</td>
<td>1</td>
<td>is the value non a number (added in version 0.4)</td>
</tr>
<tr>
<td>copysign()</td>
<td>1</td>
<td>copy sign of a number(added in version 0.4)</td>
</tr>
<tr>
<td>imodf()</td>
<td>1</td>
<td>   get signed integer value from floating point number(added in version 0.4)</td>
</tr>
<tr>
<td>modf()</td>
<td>1</td>
<td>get signed fractional value from floating-point number(added in version 0.4)</td>
</tr>
<tr>
<td>drem()</td>
<td>2</td>
<td>floating-point remainder function (added in version 0.4)</td>
</tr>
<tr>
<td>fmod()</td>
<td>1</td>
<td> floating-point remainder function (added in version 0.4)</td>
</tr>
</tbody>
</table>

<p>
<!-- Power Functions -->
<B>Power Functions</B>

<table border="1" cellpadding ="10">
<thead>
<tr>
<th> Function <BR>Name </th>
<th> # of <BR>Args </th>
<th style="text-align: left">
  Description </th>
</tr>
</thead>
<tbody>
<tr>
<td>pow()</td>
<td>2</td>
<td>raise to the power of {e.g., pow(x,y) is x to the power of y}</td>
</tr>
<tr>
<td>sqrt()</td>
<td>1</td>
<td>square root</td>
</tr>
<tr>
<td>exp()</td>
<td>1</td>
<td>e raised to the power of the argument {e.g., exp(5.2) is e raised to the power of 5.2}</td>
</tr>
<tr>
<td>ln() and log()</td>
<td>1</td>
<td>natural log</td>
</tr>
<tr>
<td>log10()</td>
<td>1</td>
<td>log base 10</td>
</tr>
<tr>
<td>fact()</td>
<td>1</td>
<td>factorial</td>
</tr>
<tr>
<td>erf()</td>
<td>1</td>
<td>error function (added in version 0.4)</td>
</tr>
<tr>
<td>erfc()</td>
<td>1</td>
<td>complementary error function (added in version 0.4)</td>
</tr>
<tr>
<td>cbrt()</td>
<td>1</td>
<td>cube root (added in version 0.4)</td>
</tr>
<tr>
<td>expm1()</td>
<td>1</td>
<td>exponential minus 1 (added in version 0.4)</td>
</tr>
<tr>
<td>log1p()</td>
<td>1</td>
<td>logarithm of 1 plus (added in version 0.4)</td>
</tr>
<tr>
<td>ldexp()</td>
<td>1</td>
<td>multiply floating-point number by integral power of 2 (added in version 0.4)</td>
</tr>
</tbody>
</table>

<p>
<!-- Trigonometric Functions -->
<B>Trigonometric (all trigonometric functions here expect radian values)</B>
<table border="1" cellpadding ="10">
<thead>
<tr>
<th> Function <BR>Name </th>
<th> # of <BR>Args </th>
<th style="text-align: left">
  Description </th>
</tr>
</thead>
<tbody>
<tr>
<td>sin()</td>
<td>1</td>
<td>sine</td>
</tr>
<tr>
<td>cos()</td>
<td>1</td>
<td>cosine</td>
</tr>
<tr>
<td>tan()</td>
<td>1</td>
<td>tangent</td>
</tr>
<tr>
<td>asin()</td>
<td>1</td>
<td>arc sine</td>
</tr>
<tr>
<td>acos()</td>
<td>1</td>
<td>arc cosine</td>
</tr>
<tr>
<td>atan()</td>
<td>1</td>
<td>arc tangent</td>
</tr>
<tr>
<td>atan2()</td>
<td>2</td>
<td>arc tangent of 2 variables</td>
</tr>
<tr>
<td>sinh()</td>
<td>1</td>
<td>hyperbolic sine</td>
</tr>
<tr>
<td>cosh()</td>
<td>1</td>
<td>hyperbolic cosine</td>
</tr>
<tr>
<td>tanh()</td>
<td>1</td>
<td>hyperbolic tangent</td>
</tr>
<tr>
<td>asinh()</td>
<td>1</td>
<td>inverse hyperbolic sine</td>
</tr>
<tr>
<td>acosh()</td>
<td>1</td>
<td>inverse hyperbolic cosine</td>
</tr>
<tr>
<td>atan()</td>
<td>1</td>
<td>inverse hyperbolic tangent</td>
</tr>
<tr>
<td>hypot()</td>
<td>2</td>
<td> euclidean distance function (0 to this location)</td>
</tr>
</tbody>
</table>


<p>
<!-- Table Functions -->
<B> Table Functions </B>
</p>
<table border="1" cellpadding ="10">
<thead>
<tr>
		<th> Function <BR> Name </th>
		<th style="text-align:center;"> # of <BR> Args </th>
		<th style="text-align:left;"> Description</th>
</tr>
</thead>
<tbody>
<tr>
		<td>size()</td>
		<td>1</td>
		<td style="text-align:left;">size of a table</td>
</tr>
<tr>
		<td>sum()</td>
		<td>1</td>
		<td style="text-align:left;">sum of all elements of a table</td>
</tr>
<tr>
		<td>Sum()</td>
		<td>3</td>
		<td style="text-align:left;">sum of elements of a specified boundary of a table</td>
</tr>
<tr>
		<td>avg()</td>
		<td>1</td>
		<td style="text-align:left;">averages all elements of a table</td>
</tr>
<tr>
		<td>Avg()</td>
		<td>3</td>
		<td style="text-align:left;">averages elements of a specified boundary of a table</td>
</tr>
</tbody>
</table>


<p>
<strong>
Acoustics Functions
</strong>
</p>
<table border="1" cellpadding ="10">
<thead>
<tr>
		<th> Function <BR> Name </th>
		<th> # of <BR>Args </th>
<th style="text-align:left;"> Description </th>
</tr>
</thead>
<tbody>
<tr>
<td> mtof()    </td>
<td> 1         </td>
<td style="text-align:left;"> convert MIDI pitch to frequency in hertz </td>
</tr>
<tr>
<td> ftom()    </td>
<td> 1         </td>
<td style="text-align:left;"> convert frequency in hertz to MIDI pitch </td>
</tr>
<tr>
<td> dbtorms() </td>
<td> 1         </td>
<td style="text-align:left;"> convert db to rms                        </td>
</tr>
<tr>
<td> rmstodb() </td>
<td> 1         </td>
<td style="text-align:left;"> convert rms to db                        </td>
</tr>
<tr>
<td> powtodb() </td>
<td> 1         </td>
<td style="text-align:left;"> convert power to db                      </td>
</tr>
<tr>
<td> dbtopow() </td>
<td> 1         </td>
<td style="text-align:left;"> convert db to power                      </td>
</tr>
</tbody>
</table>

<p>
<B> String Manipulation Functions (the ones that return a symbol only work for [expr])</b>
<table border="1" cellpadding ="10">
<thead>
<tr>
<th style="width:50%" align="left">Function <BR> Name  </th>
<th> # of <BR> Args </th>
<th> returns </th>
<th style="text-align:left;width:30%"> Description  </th>
</tr>
</thead>
<tbody>
<tr style="vertical-align:top">
	<td> symbol(int/float/symbol [, int X, int Y])<BR>sym(int/float/symbol) </td>
<td> 0, 1, 2, or 3         </td>
<td> symbol         </td>
<td style="text-align:left;"> symbol formatted based on the type of the input
<BR>
<BR>
0 argument will result in an empty symbol
<BR>
<BR>

1 argument will produce a symbol from string/symbol, int, float, according to the %s, %d, %f syntax in sprintf() respectively
<BR>
<BR>
2 argument (sym, X) will produce a symbol from string/symbol, int, float, according to the %Xs, %.Xd, %.Xf syntax in sprintf() respectively

<BR>
<BR>

3 arguments (sym, X, Y) will produce a symbol from string/symbol, int, float, according to the %Y.Xs, %Y.Xd, %Y.Xf syntax in sprintf() respectively
</tr>
<tr style="vertical-align:top">
	<td> var(symbol)</td>
	<td> 1         </td>
	<td> float         </td>
	<td style="text-align:left;"> var() will treat the value of the symbol argument as a variable name and returns the value of the variable
</tr>
<tr>
<td> strlen(symbol) </td>
<td> 1         </td>
<td> int         </td>
<td style="text-align:left;"> length of symbol
</tr>
<tr style="vertical-align:top">
<td> tolower(symbol)</td>
<td> 1</td>
<td> symbol         </td>
<td stype="text-align:left;" valign="top"> convert all upper-case letters of the string to the corresponding lower-case letters
</td>
</tr>
<tr style="vertical-align:top">
<td> tonlower(symbol, int)</td>
<td> 2</td>
<td> symbol         </td>
<td stype="text-align:left;" valign="top"> convert n'th character of the string from upper-case letter to the corresponding lower-case letter
</td>
</tr>
<tr style="vertical-align:top">
<td>
toupper(symbol)</td>
<td> 1</td>
<td> symbol         </td>
<td stype="text-align:left;"> convert all lower-case letters of the string to the corresponding upper-case letters
</td>
</tr>
<tr style="vertical-align:top">
<td> tonupper(symbol, int)</td>
<td> 2</td>
<td> symbol         </td>
<td stype="text-align:left;"> convert n'th character of the string from lower-case letter to the corresponding upper-case letter
</td>
</tr>
<tr style="vertical-align:top">
<td> strcat(symbol, symbol, ...)</td>
<td> var</td>
<td> symbol         </td>
<td stype="text-align:left;">  Concatenate two or more strings
</td>
</tr>
<tr style="vertical-align:top">
<td> strncat(symbol, symbol, int)</td>
<td> 3</td>
<td> symbol         </td>
<td stype="text-align:left;">  Contatenate the first string, by no more than n characters of the second string
</td>
</tr>
<tr style="vertical-align:top">
<td> strcmp(symbol, symbol)</td>
<td> 2</td>
<td> int         </td>
<td stype="text-align:left;"> Compare two strings; return an integer greater than, equal to, or less than 0, according as the first string is greater than,
     equal to, or less than the second string.
</td>
</tr>
<tr style="vertical-align:top">
<td> strncmp(symbol, symbol, int)</td>
<td> 3</td>
<td> int         </td>
<td stype="text-align:left;"> Compare no more than n characters of two strings; return an integer greater than, equal to, or less than 0, according as the first string is greater than,
</tr>
<tr style="vertical-align:top">
<td> strcasecmp(symbol, symbol)</td>
<td> 2</td>
<td> int         </td>
<td stype="text-align:left;"> similar to strcmp() but ignore case of the letters
</td>
</tr>
<tr style="vertical-align:top">
<td> strncasecmp(symbol, symbol, int)</td>
<td> 3</td>
<td> int         </td>
<td stype="text-align:left;"> similar to strncmp() but ignore case of the letters
</td>
</tr>
<tr style="vertical-align:top">
<td> strpbrk(symbol, symbol)</td>
<td> 2</td>
<td> symbol         </td>
<td stype="text-align:left;"> In the first string locate the first
     occurrence of any character in the second (character set) string and
	 return a substring of the first string starting with the found character.
     If no characters from  second string is found return 0;
</td>
</tr>
<tr style="vertical-align:top">
<td> strspn(symbol, symbol)</td>
<td> 2</td>
<td> int         </td>
<td stype="text-align:left;"> return the string array index of the first character of the first string which is not in the
        second (charset) string, else return the index of the first null character.
</td>
</tr>
<tr style="vertical-align:top">
<td> strcspn(symbol, symbol)</td>
<td> 2</td>
<td> int         </td>
<td stype="text-align:left;"> return the string array index of the first character of the
        first string  which is also in charset, else return the index of the first null character.
</td>
</tr>
</tbody>
</table>


<BR>
<p>
<hr width="100%" size="2" align="left">

<h3 id="CHANGELOG:">CHANGELOG:</h3>

<h3 id="version.0.58">version 0.58</h3>
<ul>
<li>Added string functions in [expr]; now expr can output symbols (major redesign) </li>
<li>Provide better error messages; now expr prints the [expr] string when reporting errors
<li>Fixed the [expr~] array[0]" bug
<li>Fixed a memory issue were extra unused output vectors were <BR>
  allocated for each inlet
<li> NOTE: the syntax func("$s#", ...) is now deprecated and func($s#, ...) should be used
</ul>

<h3 id="version.0.57">version 0.57</h3>

<ul>
<li>fixed a bug in fact().</li>
<li>fact() (factorial) now calculates and returns its value in double</li>
<li>fixed the bad lvalue bug - &ldquo;4 + 5 = 3&rdquo; was not caught before</li>
<li>Added mtof(), mtof(), dbtorms(), rmstodb(), powtodb(), dbtopow()</li>
</ul>


<h3 id="version.0.56">version 0.56</h3>

<ul>
<li>[fexpr~] now accepts a float in its first input.</li>
<li>Added avg() and Avg() back to the list of functions</li>
</ul>


<h3 id="version.0.55">version 0.55</h3>

<ul>
<li>The arrays now redraw after a store into one of their members</li>
<li>ex_if() (the &ldquo;if()&rdquo; function is reworked to only evaluate either the left or the right args depending on the truth  value of the condition. However, if the condition is an audio vector, both the left and the right are evaluated regardless.</li>
<li>priority of &lsquo;,&rsquo; and &lsquo;=&rsquo; was switched to fix the bug of using store &ldquo;=&rdquo; in functions with multiple arguments, which caused  an error during execution.</li>
<li>The number of inlet and outlets (MAX_VARS) is now set at 100</li>
</ul>


<h3 id="version.0.5">version 0.5</h3>

<ul>
<li>[expr], [expr~], and [fexpr~] are now built-in native objects.</li>
<li>minor fixes/improvements.</li>
</ul>


<h3 id="version.0.4">version 0.4</h3>

<ul>
<li>[expr], [expr~], and [fexpr~] now support multiple expressions separated by semicolons which results in multiple outlets.</li>
<li>Variables are supported now in the same way they are supported in C.  - Variables have to be defined with the &ldquo;value&rdquo; object prior to execution.</li>
<li>A new if function  if (condition-expression, IfTrue-expression, IfFalse-expression) has been added.</li>
<li>New math functions added.</li>
<li>New shorthand notations for [fexpr~] have been added.

<ul>
<li>$x ->$x1[0]     $x# -> $x#[0]</li>
<li>$y = $y1[-1] and $y# = $y#[-1]</li>
</ul>
</li>
<li>New &lsquo;set&rsquo; and &lsquo;clear&rsquo; methods were added for [fexpr~]

<ul>
<li>clear - clears all the past input and output buffers</li>
<li>clear x# - clears all the past values of the #th input</li>
<li>clear y# - clears all the past values of the #th output</li>
<li>set x# val-1 val-2 &hellip; - sets as many supplied value of the         #th input;
e.g., &ldquo;set x2 3.4 0.4&rdquo;  - sets x2[-1]=3.4 and x2[-2]=0.4</li>
<li>set y# val-1 val-2 &hellip; - sets as many supplied values of the #th output;
e.g, &ldquo;set y3 1.1 3.3 4.5&rdquo; -  sets y3[-1]=1.1 y3[-2]=3.3 and y3[-3]=4.5;</li>
<li>set val val &hellip; - sets the first past values of each output; e.g.,
e.g., &ldquo;set 0.1 2.2 0.4&rdquo;  - sets y1[-1]=0.1, y2[-1]=2.2, y3[-1]=0.4</li>
</ul>
</li>
</ul>

</body>
</html>
